/**
 * 信用系统通用混入
 */
import { getCreditLevel, formatCreditScore, getCreditGapInfo } from '@/utils/credit/creditScore'
import { formatAmount, formatDateTime, formatRelativeTime } from '@/utils/credit/validation'

export const creditMixin = {
  data() {
    return {
      // 通用加载状态
      creditLoading: false,
      // 信用分刷新定时器
      creditRefreshTimer: null
    }
  },
  
  methods: {
    /**
     * 获取信用等级
     */
    getCreditLevel,
    
    /**
     * 格式化信用分
     */
    formatCreditScore,
    
    /**
     * 获取信用分差距信息
     */
    getCreditGapInfo,
    
    /**
     * 格式化金额
     */
    formatAmount,
    
    /**
     * 格式化日期时间
     */
    formatDateTime,
    
    /**
     * 格式化相对时间
     */
    formatRelativeTime,
    
    /**
     * 显示信用分变化动画
     * @param {number} oldScore 旧分数
     * @param {number} newScore 新分数
     * @param {Function} callback 回调函数
     */
    animateCreditScore(oldScore, newScore, callback) {
      if (!oldScore || !newScore || oldScore === newScore) {
        callback && callback(newScore)
        return
      }
      
      const duration = 2000 // 动画时长
      const startTime = Date.now()
      const diff = newScore - oldScore
      
      const updateScore = () => {
        const elapsed = Date.now() - startTime
        const progress = Math.min(elapsed / duration, 1)
        
        // 使用缓动函数
        const easeOutQuart = 1 - Math.pow(1 - progress, 4)
        const currentScore = Math.round(oldScore + diff * easeOutQuart)
        
        callback && callback(currentScore)
        
        if (progress < 1) {
          requestAnimationFrame(updateScore)
        }
      }
      
      requestAnimationFrame(updateScore)
    },
    
    /**
     * 检查服务资格
     * @param {number} userScore 用户信用分
     * @param {number} requiredScore 要求信用分
     * @returns {object} 检查结果
     */
    checkServiceEligibility(userScore, requiredScore) {
      const eligible = userScore >= requiredScore
      
      return {
        eligible,
        userScore,
        requiredScore,
        gap: requiredScore - userScore,
        message: eligible 
          ? '您的信用分满足使用条件' 
          : `还需提升${requiredScore - userScore}分才能使用此服务`
      }
    },
    
    /**
     * 计算信用优惠
     * @param {number} score 信用分
     * @param {number} originalPrice 原价
     * @returns {object} 优惠信息
     */
    calculateCreditDiscount(score, originalPrice) {
      let discountRate = 0
      
      if (score >= 800) {
        discountRate = 0.2 // 20%优惠
      } else if (score >= 750) {
        discountRate = 0.15 // 15%优惠
      } else if (score >= 700) {
        discountRate = 0.1 // 10%优惠
      } else if (score >= 650) {
        discountRate = 0.05 // 5%优惠
      }
      
      const discountAmount = originalPrice * discountRate
      const finalPrice = originalPrice - discountAmount
      
      return {
        discountRate: Math.round(discountRate * 100),
        discountAmount: Math.round(discountAmount),
        finalPrice: Math.round(finalPrice),
        hasDiscount: discountRate > 0
      }
    },
    
    /**
     * 显示信用分提示
     * @param {number} score 信用分
     * @param {string} context 上下文
     */
    showCreditTip(score, context = '') {
      const level = this.getCreditLevel(score)
      const message = context 
        ? `${context}（当前信用等级：${level.name}）`
        : `您的信用等级：${level.name}`
      
      this.$message({
        message,
        type: level.level === 'excellent' || level.level === 'good' ? 'success' : 'warning',
        duration: 3000,
        showClose: true
      })
    },
    
    /**
     * 跳转到信用分页面
     */
    goToCreditScore() {
      this.$router.push('/credit/score')
    },
    
    /**
     * 跳转到提升任务页面
     */
    goToImproveTasks() {
      this.$router.push('/credit/score?tab=tasks')
    },
    
    /**
     * 启动信用分定时刷新
     * @param {Function} refreshCallback 刷新回调
     * @param {number} interval 刷新间隔(毫秒)
     */
    startCreditRefresh(refreshCallback, interval = 60000) {
      this.stopCreditRefresh()
      
      this.creditRefreshTimer = setInterval(() => {
        if (typeof refreshCallback === 'function') {
          refreshCallback()
        }
      }, interval)
    },
    
    /**
     * 停止信用分定时刷新
     */
    stopCreditRefresh() {
      if (this.creditRefreshTimer) {
        clearInterval(this.creditRefreshTimer)
        this.creditRefreshTimer = null
      }
    },
    
    /**
     * 复制文本到剪贴板
     * @param {string} text 要复制的文本
     * @param {string} successMessage 成功消息
     */
    copyToClipboard(text, successMessage = '复制成功') {
      if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(text).then(() => {
          this.$message.success(successMessage)
        }).catch(err => {
          console.error('复制失败:', err)
          this.fallbackCopyToClipboard(text, successMessage)
        })
      } else {
        this.fallbackCopyToClipboard(text, successMessage)
      }
    },
    
    /**
     * 降级复制方法
     */
    fallbackCopyToClipboard(text, successMessage) {
      const textArea = document.createElement('textarea')
      textArea.value = text
      textArea.style.position = 'fixed'
      textArea.style.opacity = '0'
      document.body.appendChild(textArea)
      textArea.focus()
      textArea.select()
      
      try {
        document.execCommand('copy')
        this.$message.success(successMessage)
      } catch (err) {
        console.error('降级复制失败:', err)
        this.$message.error('复制失败，请手动复制')
      }
      
      document.body.removeChild(textArea)
    },
    
    /**
     * 下载文件
     * @param {string} url 文件URL
     * @param {string} filename 文件名
     */
    downloadFile(url, filename) {
      const link = document.createElement('a')
      link.href = url
      link.download = filename || '文件'
      link.style.display = 'none'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    },
    
    /**
     * 节流函数装饰器
     * @param {Function} func 要节流的函数
     * @param {number} delay 延迟时间
     */
    throttle(func, delay = 300) {
      let timer = null
      return (...args) => {
        if (!timer) {
          timer = setTimeout(() => {
            func.apply(this, args)
            timer = null
          }, delay)
        }
      }
    },
    
    /**
     * 防抖函数装饰器
     * @param {Function} func 要防抖的函数
     * @param {number} delay 延迟时间
     */
    debounce(func, delay = 300) {
      let timer = null
      return (...args) => {
        clearTimeout(timer)
        timer = setTimeout(() => {
          func.apply(this, args)
        }, delay)
      }
    }
  },
  
  beforeDestroy() {
    // 清理定时器
    this.stopCreditRefresh()
  }
}

/**
 * 表格混入 - 用于数据表格页面
 */
export const tableMixin = {
  data() {
    return {
      // 表格数据
      tableData: [],
      // 表格加载状态
      tableLoading: false,
      // 分页信息
      pagination: {
        current: 1,
        size: 10,
        total: 0
      },
      // 查询参数
      queryParams: {},
      // 选中的行
      selectedRows: []
    }
  },
  
  methods: {
    /**
     * 获取表格数据
     */
    async getTableData() {
      this.tableLoading = true
      try {
        const params = {
          pageNum: this.pagination.current,
          pageSize: this.pagination.size,
          ...this.queryParams
        }
        
        // 子组件需要实现这个方法
        const response = await this.fetchTableData(params)
        
        if (response.code === 200) {
          this.tableData = response.rows || []
          this.pagination.total = response.total || 0
        }
      } catch (error) {
        console.error('获取表格数据失败:', error)
        this.$message.error('获取数据失败')
      } finally {
        this.tableLoading = false
      }
    },
    
    /**
     * 处理分页变化
     */
    handlePageChange(page) {
      this.pagination.current = page
      this.getTableData()
    },
    
    /**
     * 处理每页大小变化
     */
    handleSizeChange(size) {
      this.pagination.size = size
      this.pagination.current = 1
      this.getTableData()
    },
    
    /**
     * 处理查询
     */
    handleQuery() {
      this.pagination.current = 1
      this.getTableData()
    },
    
    /**
     * 重置查询
     */
    handleReset() {
      this.queryParams = {}
      this.handleQuery()
    },
    
    /**
     * 处理选择变化
     */
    handleSelectionChange(selection) {
      this.selectedRows = selection
    },
    
    /**
     * 批量删除
     */
    async handleBatchDelete() {
      if (this.selectedRows.length === 0) {
        this.$message.warning('请选择要删除的数据')
        return
      }
      
      try {
        await this.$confirm('确定要删除选中的数据吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        
        // 子组件需要实现这个方法
        await this.deleteBatch(this.selectedRows)
        
        this.$message.success('删除成功')
        this.getTableData()
      } catch (error) {
        if (error !== 'cancel') {
          console.error('批量删除失败:', error)
          this.$message.error('删除失败')
        }
      }
    }
  },
  
  mounted() {
    this.getTableData()
  }
}

/**
 * 表单混入 - 用于表单页面
 */
export const formMixin = {
  data() {
    return {
      // 表单数据
      formData: {},
      // 表单验证规则
      formRules: {},
      // 表单加载状态
      formLoading: false,
      // 表单模式 add/edit/view
      formMode: 'add'
    }
  },
  
  methods: {
    /**
     * 提交表单
     */
    async handleSubmit() {
      try {
        // 验证表单
        await this.$refs.form.validate()
        
        this.formLoading = true
        
        // 子组件需要实现这个方法
        if (this.formMode === 'add') {
          await this.createData(this.formData)
          this.$message.success('创建成功')
        } else if (this.formMode === 'edit') {
          await this.updateData(this.formData)
          this.$message.success('更新成功')
        }
        
        this.handleCancel()
      } catch (error) {
        if (error !== 'cancel') {
          console.error('提交表单失败:', error)
          this.$message.error('操作失败')
        }
      } finally {
        this.formLoading = false
      }
    },
    
    /**
     * 取消操作
     */
    handleCancel() {
      this.$refs.form.resetFields()
      this.formData = {}
      this.formMode = 'add'
      this.$emit('cancel')
    },
    
    /**
     * 重置表单
     */
    handleReset() {
      this.$refs.form.resetFields()
    }
  }
} 